﻿using CMS.AOP;
using CMS.DataAccess;
using CMS.Excep;
using CMS.Model;
using CMS.Utils;

namespace CMS.ServiceProvider
{
    public class ScheduleServiceProvider : BaseServiceProvider<ScheduleModel>
    {
        public ScheduleServiceProvider() 
        {
            this.udpInstance.RegBeforeSaveAction(new ScheduleConflictSaveAction());
            this.AddDefaultValueSetter(new ScheduleDefValueSetter());
        }

        public void RemoveByDseClass(string dseClass, string startDate, string endDate)
        {
            var list = ListByClass(dseClass, startDate, endDate);
            foreach (var item in list)
            {
                Delete(item.Pk);
            }
        }
        public List<ScheduleModel> ListByClass(string dseClass, string startDate, string endDate)
        {
            var list = List(CondCollection.True().Eq(nameof(ScheduleModel.DseClass), dseClass)
                .Ge(nameof(ScheduleModel.Date), startDate)
                .Le(nameof(ScheduleModel.Date), endDate));
            return list;
        }
        public List<ScheduleModel> ListByTeacher(string teacher, string startDate, string endDate)
        {
            var list = List(CondCollection.True().Eq(nameof(ScheduleModel.Teacher), teacher)
                .Ge(nameof(ScheduleModel.Date), startDate)
                .Le(nameof(ScheduleModel.Date), endDate));
            return list;
        }
        public void ExchangeSchedule(string one,string other)
        {
            if (String.IsNullOrWhiteSpace(one) && !String.IsNullOrWhiteSpace(other))
                Delete(other);
            if (!String.IsNullOrWhiteSpace(one) && String.IsNullOrWhiteSpace(other))
                Delete(one);
            if (String.IsNullOrWhiteSpace(one) && String.IsNullOrWhiteSpace(other))
                throw new MyNullException("参数有误");
            var cSP = ServiceLoader.GetService<CourseServiceProvider>();
            var _one = Get(one);
            var _other = Get(other);
            var cOne = cSP.Get(_one.Course);
            var cOther = cSP.Get(_other.Course);
            string swap = _one.Teacher;
            _one.Teacher = _other.Teacher;
            _other.Teacher = swap;
            swap = _one.Course;
            _one.Course = _other.Course;
            _other.Course = swap;
            swap = _one.Color;
            _one.Color = _other.Color;
            _other.Color = swap;
            _one.Note = $"与{_other.Date} {_other.Start}{cOne.CourseName}对调";
            _other.Note = $"与{_one.Date} {_one.Start}{cOther.CourseName}对调";
            Save(_one);
            Save(_other);
        }

        public void Move(string from, string to)
        {
            var r1= List(CondCollection.True().Eq(nameof(ScheduleModel.Date), from));
            var r2 = List(CondCollection.True().Eq(nameof(ScheduleModel.Date), to));
            foreach (var r in r2)
            {
                Delete(r.Pk);
            }
            foreach (var r in r1)
            {
                r.Note = $"从{r.Date}调入";
                r.Date = to;
                Save(r);
            }
        }
        public List<ScheduleModel> ConvertFromTemplate(string dseClass, DateTime startDate, DateTime endDate)
        {
            var result = new List<ScheduleModel>();
            var templateSP = ServiceLoader.GetService<ScheduleTemplateServiceProvider>();
            var timetableSp = ServiceLoader.GetService<TimeTableServiceProvider>();
            var timetable = timetableSp.List(CondCollection.True(), 0, 1000, out int total);
            var timetable_a = timetable.Where(r => r.Weekday != -1);
            var timetable_b = timetable.Where(r => r.Weekday == -1);
            var temps = templateSP.ListByClass(dseClass);
            RemoveByDseClass(dseClass, startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd"));
            var date = startDate;
            while (date <= endDate)
            {
                var _temps = temps.Where(r => r.WeekDay == date.DayOfWeek);
                foreach (var temp in _temps)
                {
                    var model = new ScheduleModel()
                    {
                        Color = temp.Color,
                        Date = date.ToString("yyyy-MM-dd"),
                        DseClass = temp.DseClass,
                        Seq = temp.Seq,
                        Teacher = temp.Teacher,
                        WeekDay = temp.WeekDay,
                        RefWeekDay = temp.WeekDay,
                        Course = temp.Course,
                        Optional= temp.Optional,
                        GroupClass = temp.GroupClass,
                    };
                    var matchTimeTable = timetable_a.FirstOrDefault(r => r.Seq == model.Seq && r.Weekday == (int)model.WeekDay);
                    if (matchTimeTable != null)
                    {
                        model.Start = matchTimeTable.Start;
                        model.End = matchTimeTable.End;
                    }
                    else 
                    {
                        var matchTimeTable2 = timetable_b.First(r => r.Seq == model.Seq);
                        model.Start = matchTimeTable2.Start;
                        model.End = matchTimeTable2.End;
                    }
                    Save(model);
                    result.Add(model);
                }
                date = date.AddDays(1);
            }
            return result;
        }
    }
}
